/**
 * XL-Payment 多端支付聚合SDK
 * 提供微信/支付宝/银联/国际卡统一支付接口，支持虚拟货币混合支付
 */
import store from './store';
import { getAdapterByType } from './adapters';
import { OrderManager } from './order';
import { generateOrderId, formatAmount, mergeConfig } from './utils';
import defaultConfig from './config';

class XlPayment {
  constructor(config = {}) {
    // 合并配置
    this.config = mergeConfig(defaultConfig, config);
    
    // 初始化状态管理
    this.store = store;
    
    // 初始化订单管理器
    this.orderManager = new OrderManager({
      store: this.store,
      config: this.config
    });
    
    // 支付中的订单缓存
    this.pendingOrders = new Map();
    
    // 初始化事件监听
    this._initEventListeners();
  }
  
  /**
   * 初始化支付环境
   * @param {Object} options 初始化选项
   * @returns {Promise} 初始化结果
   */
  async initialize(options = {}) {
    try {
      // 更新配置
      if (options.config) {
        this.config = mergeConfig(this.config, options.config);
      }
      
      // 检查环境
      const env = uni.getSystemInfoSync();
      this.store.setEnv({
        platform: env.platform,
        system: env.system,
        appName: env.appName,
        isH5: process.env.UNI_PLATFORM === 'h5',
        isApp: process.env.UNI_PLATFORM === 'app',
        isMP: process.env.UNI_PLATFORM.indexOf('mp-') !== -1
      });
      
      // 记录初始化状态
      this.store.setState({ initialized: true });
      
      // 同步未完成订单状态（如果开启了该选项）
      if (this.config.syncPendingOrders) {
        await this.orderManager.syncPendingOrders();
      }
      
      return { success: true };
    } catch (error) {
      this.store.setError({
        code: 'INIT_FAILED',
        message: '支付SDK初始化失败: ' + (error.message || error),
        details: error
      });
      return { success: false, error };
    }
  }
  
  /**
   * 创建支付订单
   * @param {Object} orderInfo 订单信息
   * @returns {Promise} 创建结果
   */
  async createOrder(orderInfo) {
    try {
      // 参数验证
      if (!orderInfo.amount) {
        throw new Error('订单金额不能为空');
      }
      
      // 标准化订单信息
      const order = {
        id: orderInfo.orderId || generateOrderId(),
        title: orderInfo.title || '商品购买',
        amount: formatAmount(orderInfo.amount),
        currency: orderInfo.currency || 'CNY',
        createdAt: new Date().toISOString(),
        paymentType: orderInfo.paymentType || 'wechat',
        status: 'CREATED',
        extra: orderInfo.extra || {},
        virtualAmount: formatAmount(orderInfo.virtualAmount || 0),
        items: orderInfo.items || [],
        metadata: orderInfo.metadata || {}
      };
      
      // 保存订单
      await this.orderManager.saveOrder(order);
      
      // 添加到待处理订单
      this.pendingOrders.set(order.id, { order, timestamp: Date.now() });
      
      return { success: true, order };
    } catch (error) {
      this.store.setError({
        code: 'CREATE_ORDER_FAILED',
        message: '创建订单失败: ' + (error.message || error),
        details: error
      });
      return { success: false, error };
    }
  }
  
  /**
   * 发起支付
   * @param {Object} options 支付选项
   * @returns {Promise} 支付结果
   */
  async pay(options) {
    try {
      // 参数验证
      if (!options.orderId && !options.order) {
        throw new Error('订单信息不能为空');
      }
      
      // 获取订单信息
      let order = options.order;
      if (!order && options.orderId) {
        order = await this.orderManager.getOrder(options.orderId);
        if (!order) {
          throw new Error(`订单不存在: ${options.orderId}`);
        }
      }
      
      // 检查是否重复支付
      if (order.status === 'PAID' || order.status === 'SUCCESS') {
        return { success: true, duplicate: true, order };
      }
      
      // 更新订单状态
      order.status = 'PAYING';
      await this.orderManager.updateOrder(order);
      
      // 获取支付渠道适配器
      const paymentType = options.paymentType || order.paymentType;
      const adapter = getAdapterByType(paymentType);
      if (!adapter) {
        throw new Error(`不支持的支付方式: ${paymentType}`);
      }
      
      // 混合支付处理
      let realAmount = order.amount;
      if (order.virtualAmount && order.virtualAmount > 0) {
        // 虚拟货币支付部分
        const virtualAdapter = getAdapterByType('virtual');
        const virtualResult = await virtualAdapter.pay({
          order,
          amount: order.virtualAmount,
          config: this.config.virtual
        });
        
        if (!virtualResult.success) {
          throw new Error('虚拟货币支付失败: ' + virtualResult.message);
        }
        
        // 更新实际需要支付的金额
        realAmount = Math.max(0, order.amount - order.virtualAmount);
        if (realAmount <= 0) {
          // 全部用虚拟货币支付完成
          order.status = 'PAID';
          order.paidAt = new Date().toISOString();
          await this.orderManager.updateOrder(order);
          return { success: true, order };
        }
      }
      
      // 调用渠道支付
      const payResult = await adapter.pay({
        order,
        amount: realAmount,
        config: this.config[paymentType],
        env: this.store.state.env
      });
      
      if (!payResult.success) {
        throw new Error(`支付失败: ${payResult.message || '未知错误'}`);
      }
      
      // 支付完成后的订单状态更新会通过异步通知或轮询来完成
      return { success: true, ...payResult, order };
    } catch (error) {
      // 支付失败，恢复订单状态
      if (options.orderId) {
        const order = await this.orderManager.getOrder(options.orderId);
        if (order && order.status === 'PAYING') {
          order.status = 'CREATED';
          await this.orderManager.updateOrder(order);
        }
      }
      
      this.store.setError({
        code: 'PAYMENT_FAILED',
        message: '支付失败: ' + (error.message || error),
        details: error
      });
      return { success: false, error };
    }
  }
  
  /**
   * 查询订单状态
   * @param {String} orderId 订单ID
   * @returns {Promise} 查询结果
   */
  async queryOrder(orderId) {
    try {
      const order = await this.orderManager.getOrder(orderId);
      if (!order) {
        throw new Error(`订单不存在: ${orderId}`);
      }
      
      // 如果订单状态不是终态，则查询最新状态
      if (['CREATED', 'PAYING'].includes(order.status)) {
        const adapter = getAdapterByType(order.paymentType);
        if (adapter) {
          const result = await adapter.queryOrder({
            order,
            config: this.config[order.paymentType]
          });
          
          if (result.success && result.status) {
            order.status = result.status;
            if (order.status === 'PAID' || order.status === 'SUCCESS') {
              order.paidAt = result.paidAt || new Date().toISOString();
            } else if (order.status === 'FAILED' || order.status === 'CLOSED') {
              order.closedAt = result.closedAt || new Date().toISOString();
            }
            await this.orderManager.updateOrder(order);
          }
        }
      }
      
      return { success: true, order };
    } catch (error) {
      this.store.setError({
        code: 'QUERY_FAILED',
        message: '查询订单失败: ' + (error.message || error),
        details: error
      });
      return { success: false, error };
    }
  }
  
  /**
   * 关闭订单
   * @param {String} orderId 订单ID
   * @returns {Promise} 关闭结果
   */
  async closeOrder(orderId) {
    try {
      const order = await this.orderManager.getOrder(orderId);
      if (!order) {
        throw new Error(`订单不存在: ${orderId}`);
      }
      
      // 终态订单不能关闭
      if (['PAID', 'SUCCESS', 'CLOSED', 'FAILED'].includes(order.status)) {
        return { success: true, order, alreadyClosed: true };
      }
      
      // 调用渠道关闭
      const adapter = getAdapterByType(order.paymentType);
      if (adapter && typeof adapter.closeOrder === 'function') {
        await adapter.closeOrder({
          order,
          config: this.config[order.paymentType]
        });
      }
      
      // 更新订单状态
      order.status = 'CLOSED';
      order.closedAt = new Date().toISOString();
      await this.orderManager.updateOrder(order);
      
      return { success: true, order };
    } catch (error) {
      this.store.setError({
        code: 'CLOSE_FAILED',
        message: '关闭订单失败: ' + (error.message || error),
        details: error
      });
      return { success: false, error };
    }
  }
  
  /**
   * 退款处理
   * @param {Object} options 退款选项
   * @returns {Promise} 退款结果
   */
  async refund(options) {
    try {
      // 参数验证
      if (!options.orderId) {
        throw new Error('订单ID不能为空');
      }
      
      const order = await this.orderManager.getOrder(options.orderId);
      if (!order) {
        throw new Error(`订单不存在: ${options.orderId}`);
      }
      
      // 只有已支付的订单可以退款
      if (order.status !== 'PAID' && order.status !== 'SUCCESS') {
        throw new Error('只有已支付的订单可以申请退款');
      }
      
      // 退款金额默认为全额退款
      const refundAmount = options.amount || order.amount;
      
      // 调用渠道退款
      const adapter = getAdapterByType(order.paymentType);
      if (!adapter || typeof adapter.refund !== 'function') {
        throw new Error(`该支付方式不支持退款: ${order.paymentType}`);
      }
      
      const refundResult = await adapter.refund({
        order,
        amount: refundAmount,
        reason: options.reason || '用户申请退款',
        config: this.config[order.paymentType]
      });
      
      // 更新订单状态
      if (refundResult.success) {
        order.status = refundAmount >= order.amount ? 'REFUNDED' : 'PARTIAL_REFUNDED';
        order.refundAmount = (order.refundAmount || 0) + refundAmount;
        order.refundAt = new Date().toISOString();
        await this.orderManager.updateOrder(order);
      }
      
      return { success: true, order, ...refundResult };
    } catch (error) {
      this.store.setError({
        code: 'REFUND_FAILED',
        message: '退款失败: ' + (error.message || error),
        details: error
      });
      return { success: false, error };
    }
  }
  
  /**
   * 更新配置
   * @param {Object} config 新配置
   */
  setConfig(config) {
    this.config = mergeConfig(this.config, config);
  }
  
  /**
   * 获取当前状态
   * @returns {Object} 状态对象
   */
  getState() {
    return this.store.state;
  }
  
  /**
   * 清除错误
   */
  clearError() {
    this.store.clearError();
  }
  
  /**
   * 初始化事件监听
   * @private
   */
  _initEventListeners() {
    // 监听应用进入前台事件
    uni.onAppShow(() => {
      // 检查是否有待处理订单
      this._checkPendingOrders();
    });
    
    // 定时检查订单状态（如果启用）
    if (this.config.autoQueryInterval > 0) {
      setInterval(() => {
        this._checkPendingOrders();
      }, this.config.autoQueryInterval * 1000);
    }
  }
  
  /**
   * 检查待处理订单
   * @private
   */
  async _checkPendingOrders() {
    const now = Date.now();
    const orderTimeout = this.config.orderTimeout * 60 * 1000; // 转换为毫秒
    
    for (const [orderId, { order, timestamp }] of this.pendingOrders.entries()) {
      // 跳过已经处理的订单
      if (['PAID', 'SUCCESS', 'FAILED', 'CLOSED', 'REFUNDED'].includes(order.status)) {
        this.pendingOrders.delete(orderId);
        continue;
      }
      
      // 处理超时订单
      if (now - timestamp > orderTimeout) {
        // 尝试关闭订单
        await this.closeOrder(orderId).catch(() => {});
        this.pendingOrders.delete(orderId);
        continue;
      }
      
      // 查询订单状态
      const result = await this.queryOrder(orderId).catch(() => ({ success: false }));
      if (result.success) {
        const updatedOrder = result.order;
        
        // 更新缓存中的订单
        this.pendingOrders.set(orderId, { 
          order: updatedOrder, 
          timestamp 
        });
        
        // 如果订单已完成或失败，从待处理队列中移除
        if (['PAID', 'SUCCESS', 'FAILED', 'CLOSED', 'REFUNDED'].includes(updatedOrder.status)) {
          this.pendingOrders.delete(orderId);
          
          // 触发订单状态变更事件
          this.store.triggerEvent('orderStatusChange', updatedOrder);
        }
      }
    }
  }
}

// 创建默认实例
const defaultInstance = new XlPayment();

export default defaultInstance;
export { XlPayment }; 